//
//  LoadingViewSixSwnStar.swift
//  Animations
//
//  Created by aidong on 2021/9/13.
//  Copyright © 2021 sunny. All rights reserved.
//

import UIKit

class LoadingViewSixSwnStar: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    ///临时数组
    var differentColorArray = [UIColor]()
    ///三次以内禁止撞色
    func needColor() -> UIColor {
        if colorArray.count < 3 {
            return colorArray.randomElement() ?? UIColor.red
        }
        let color = colorArray.randomElement() ?? UIColor.red
        if differentColorArray.contains(color) {
            return needColor()
        } else {
            differentColorArray.append(color);
            if differentColorArray.count > 3 {
                differentColorArray.remove(at: 0)
            }
            return color
        }
    }
    
    ///开始出现小方格
    let duration_begin_show: CFTimeInterval = 0.5
    ///背景旋转
    let duration_back_totate: CFTimeInterval = 1.5
    
    ///开始动画
    func showAnimation() {
        
        /// 装所有刻度的层
        let layerAllScales = CALayer()
        //延时
        var delaytime_show: CFTimeInterval = CACurrentMediaTime();
        //底盘
        var arrayAllScales = [LoadingSixSwnStarLayer]()
        //底盘弄成正方形,
        let myWith = min(frame.width, frame.height);
        //这个是缩放的倍数,因为小方块从1点开始放大, 举例子:写40,就是放大40倍,从1点到40点,最好是偶数,这样除以二的时候精细
        let scalePix: CGFloat = 20 + CGFloat(arc4random_uniform(5) * 4)
        //找出表盘半径
        let radius_1 = frame.size.width / 2 - scalePix / 2 //为了让小方格都落在正方形的内部,所以表盘半径算出来后减掉一半的小方格子宽度
        //继续制造不同的半径 这样环形随机大小
        let radius = radius_1 * CGFloat(CGFloat(arc4random_uniform(5)) * 0.1 + 0.5)
        
        //初始底盘,添加到视图
        layerAllScales.frame = CGRect(x: (frame.width - myWith) / 2, y: (frame.height - myWith) / 2, width: myWith, height: myWith);
        //layerAllScales.backgroundColor = UIColor.orange.cgColor;
        layer.addSublayer(layerAllScales)
        
        //随机生成小方格子
        let count = CGFloat(arc4random_uniform(7) + 5)
        
        //随机颜色
        let color = needColor().cgColor
        
        for i in 0..<Int(count) {
            //初始化小方格
            let layerItem = LoadingSixSwnStarLayer()
            layerItem.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
            layerItem.lastSideLength = 0
            
            //计算位置
            let index = CGFloat(i)
            let xOff = radius * cos(-CGFloat.pi / 2 + (CGFloat.pi * 2 / count) * index)
            let yOff = radius * sin(-CGFloat.pi / 2 + (CGFloat.pi * 2 / count) * index)
            let initAngle = CGFloat.pi * 2 / count * CGFloat(i);
            layerItem.position = CGPoint(x: bounds.width / 2 + xOff, y: bounds.width / 2 + yOff)
            layerItem.backgroundColor = color
            layerItem.transform = CATransform3DMakeRotation(initAngle, 0, 0, 1)
            layerAllScales.addSublayer(layerItem)
            arrayAllScales.append(layerItem)
            
            //缩放动画
            let animation_h_1 = CAKeyframeAnimation(keyPath: "bounds.size.height")
            animation_h_1.values = calculateFrameFromValue(fromValue: layerItem.lastSideLength, toValue: scalePix, function: QuinticEaseOut, frameCount: 30)
            let animation_w_1 = CAKeyframeAnimation(keyPath: "bounds.size.width")
            animation_w_1.values = calculateFrameFromValue(fromValue: layerItem.lastSideLength, toValue: scalePix, function: QuinticEaseOut, frameCount: 30)
            layerItem.lastSideLength = scalePix; //保存新的边长
            
            //旋转动画
            let animation_r_1 = CAKeyframeAnimation(keyPath: "transform.rotation.z")
            let fromValue: CGFloat = initAngle                           //开始的位置就是方格子一开始的角度
            let toValue: CGFloat = initAngle + CGFloat.pi * CGFloat(2)   //结束的位置就是整数转圈数 + 初始的角度
            layerItem.lastRotation = toValue   //保存旋转的角度
            animation_r_1.values = calculateFrameFromValue(fromValue: fromValue, toValue: toValue, function: BounceEaseOut, frameCount: 30)
            
            //动画组
            let group_1 = CAAnimationGroup()
            group_1.duration = duration_begin_show;
            group_1.fillMode = CAMediaTimingFillMode.both
            group_1.autoreverses = false;
            group_1.isRemovedOnCompletion = false
            group_1.beginTime = delaytime_show
            group_1.animations = [animation_h_1, animation_w_1, animation_r_1]
            //开始动画
            layerItem.add(group_1, forKey: nil)
            //
            delaytime_show += 0.1
        }
        
        //背景旋转动画
        DispatchQueue.main.asyncAfter(deadline: .now() + CFTimeInterval(count * 0.1), execute: {
            
            //背景旋转动画
            let rotateTangle = CAKeyframeAnimation(keyPath: "transform.rotation.z")
            let fromValue: CGFloat = 0
            let toValue_1: CGFloat = CGFloat.pi * 0.5 + CGFloat.pi * CGFloat(arc4random_uniform(2))
            let toValue_2 = arc4random_uniform(2) % 2 == 0 ? toValue_1 * (-1) : toValue_1 //改变方向
            rotateTangle.values = calculateFrameFromValue(fromValue: fromValue, toValue: toValue_2, function: BounceEaseOut, frameCount: 30)
            rotateTangle.duration = self.duration_back_totate
            rotateTangle.fillMode = .forwards
            rotateTangle.autoreverses = false;
            rotateTangle.isRemovedOnCompletion = false
            layerAllScales.add(rotateTangle, forKey: "")
            
            //小方格消失动画
            DispatchQueue.main.asyncAfter(deadline: .now() + CFTimeInterval(self.duration_back_totate), execute: {
                //消失的时间节点
                var delaytime_disappear: CFTimeInterval = CACurrentMediaTime();
                //
                for i in 0..<Int(count) {
                    let layerItem = arrayAllScales[i]
                    //缩放动画
                    let animation_h_2 = CAKeyframeAnimation(keyPath: "bounds.size.height")
                    animation_h_2.values = calculateFrameFromValue(fromValue: layerItem.lastSideLength, toValue: 0, function: LinearInterpolation, frameCount: 30)
                    let animation_w_2 = CAKeyframeAnimation(keyPath: "bounds.size.width")
                    animation_w_2.values = calculateFrameFromValue(fromValue: layerItem.lastSideLength, toValue: 0, function: LinearInterpolation, frameCount: 30)
                    //旋转
                    let animation_r_2 = CAKeyframeAnimation(keyPath: "transform.rotation.z")
                    let fromValue: CGFloat = layerItem.lastRotation                           //开始的位置就是方格子一开始的角度
                    let toValue: CGFloat = layerItem.lastRotation + CGFloat.pi * CGFloat(4)   //结束的位置就是整数转圈数 + 初始的角度
                    animation_r_2.values = calculateFrameFromValue(fromValue: fromValue, toValue: toValue, function: LinearInterpolation, frameCount: 30)
                    //动画组
                    let group_2 = CAAnimationGroup()
                    group_2.duration = 0.5;
                    group_2.fillMode = CAMediaTimingFillMode.both
                    group_2.autoreverses = false;
                    group_2.isRemovedOnCompletion = false
                    group_2.animations = [animation_h_2, animation_w_2, animation_r_2]
                    group_2.beginTime = delaytime_disappear
                    //开始动画
                    layerItem.add(group_2, forKey: nil)
                    //
                    delaytime_disappear += 0.1
                }
                
                //把造出来的东西都扔掉,不要驻留内存
                DispatchQueue.main.asyncAfter(deadline: .now() + CFTimeInterval(count * 0.1 + 0.5), execute: {
                    layerAllScales.removeFromSuperlayer();
                    arrayAllScales.removeAll()
                })
            })
        })
    }
    
    /// 取色数组
    lazy private var colorArray: Array<UIColor> = {
        return [
            UIColor(hexStr: "ff2121"), //大红
            UIColor(hexStr: "eacd76"), //金色
            UIColor(hexStr: "e9e7ef"), //银白
            UIColor(hexStr: "000000"), //黑色
            UIColor(hexStr: "70f3ff"), //蔚蓝
            UIColor(hexStr: "bddd22"), //嫩绿
            UIColor(hexStr: "9ed900"), //葱绿
            UIColor(hexStr: "ffa631"), //杏黄
            UIColor(hexStr: "ef7a82"), //嫣红
            UIColor(hexStr: "DC143C"), //腥红之月
            UIColor(hexStr: "DAA520"), //金菊黄
            UIColor(hexStr: "FF7F50"), //珊瑚
            UIColor(hexStr: "2E8B57"), //海洋绿
            UIColor(hexStr: "8552a1"), //紫色
            UIColor(hexStr: "549688"), //铜绿
            UIColor(hexStr: "392f41"), //乌黑
            UIColor(hexStr: "ff4c00"), //朱红
        ]
    }()
}


class LoadingSixSwnStarLayer: CALayer {
    //记录上一次的旋转角度
    var lastRotation: CGFloat = 0
    //记录上一次的宽度
    var lastSideLength: CGFloat = 0
}
